#include "plan_generator.h"
#include "ast.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "plan.h"
#include "catalog.h"
#include "execution.h"

// 深拷贝AST节点（简化版）
// 参数：
// - node: 要拷贝的AST节点
// 返回值：拷贝的AST节点指针，失败返回NULL
static ASTNode* deep_copy_ast_node(ASTNode* node) {
    if (!node) return NULL;
    
    ASTNode* new_node = create_ast_node(node->type, node->token);
    new_node->left = deep_copy_ast_node(node->left);
    new_node->right = deep_copy_ast_node(node->right);
    
    // 注意：这里简化处理，没有拷贝extra_data
    // 在实际应用中，需要根据节点类型拷贝不同的extra_data
    
    return new_node;
}

// 创建计划节点
// 参数：
// - type: 计划节点类型
// 返回值：创建的计划节点指针
static PlanNode* create_plan_node(PlanNodeType type) {
    PlanNode* node = (PlanNode*)malloc(sizeof(PlanNode));
    node->type = type;
    node->params = NULL; // 使用params而不是extra_data
    node->child = NULL;
    return node;
}

// 生成CREATE TABLE执行计划
// 参数：
// - node: CREATE TABLE语句的AST节点
// - catalog: 模式目录指针
// 返回值：生成的执行计划节点
static PlanNode* generate_create_table_plan(ASTNode* node, Catalog* catalog) {
    if (!node || node->type != NODE_CREATE_TABLE) return NULL;
    
    PlanNode* plan = create_plan_node(PLAN_NODE_CREATE);
    CreateParams* data = (CreateParams*)malloc(sizeof(CreateParams));
    
    // 从AST节点的extra_data中获取CreateTableStmt
    CreateTableStmt* stmt = (CreateTableStmt*)node->extra_data;
    if (!stmt) {
        free(data);
        free(plan);
        return NULL;
    }
    
    // 填充CreateParams结构体
    data->table_name = stmt->table_name;
    data->ncols = stmt->column_count;
    
    // 分配并填充列名数组
    data->col_names = (const char**)malloc(stmt->column_count * sizeof(const char*));
    for (int i = 0; i < stmt->column_count; i++) {
        data->col_names[i] = stmt->columns[i].name;
    }
    
    PlanColType* temp_col_types = (PlanColType*)malloc(stmt->column_count * sizeof(PlanColType));
    for (int i = 0; i < stmt->column_count; i++) {
        switch (stmt->columns[i].type) {
            case TYPE_INT:
                temp_col_types[i] = PLAN_COL_INT;
                break;
            case TYPE_VARCHAR:
                temp_col_types[i] = PLAN_COL_VARCHAR;
                break;
            default:
                temp_col_types[i] = PLAN_COL_INT;
                break;
        }
    }
    data->col_types = temp_col_types;
    
    plan->params = data;
    return plan;
}

// 生成INSERT执行计划
static PlanNode* generate_insert_plan(ASTNode* node, Catalog* catalog) {
    PlanNode* plan = create_plan_node(PLAN_NODE_INSERT);
    InsertStmt* stmt = (InsertStmt*)node->extra_data;
    InsertParams* data = (InsertParams*)malloc(sizeof(InsertParams));
    
    if (!stmt || !data) {
        free(data);
        free(plan);
        return NULL;
    }
    
    data->table_name = strdup(stmt->table_name);
    data->ncols = stmt->value_count;
    
    // 设置列名数组
    if (stmt->column_count > 0) {
        data->col_names = (const char**)malloc(stmt->column_count * sizeof(const char*));
        for (int i = 0; i < stmt->column_count; i++) {
            data->col_names[i] = strdup(stmt->columns[i]);
        }
    } else {
        data->col_names = NULL;
    }
    
    // 转换AST值节点为文本值
    const char** text_values = (const char**)malloc(stmt->value_count * sizeof(const char*));
    for (int i = 0; i < stmt->value_count; i++) {
        if (!stmt->values[i] || !stmt->values[i]->token.lexeme) {
            text_values[i] = strdup("");
            continue;
        }
        
        // 安全地获取值 - 根据token类型处理值
        Token token = stmt->values[i]->token;
        if (token.type == STRING) {
            // 对于字符串类型，移除引号
            const char* lexeme = token.lexeme;
            size_t len = strlen(lexeme);
            
            // 检查是否有引号包围
            if (len >= 2 && ((lexeme[0] == '"' && lexeme[len - 1] == '"') || 
                           (lexeme[0] == '\'' && lexeme[len - 1] == '\''))) {
                // 有引号，移除引号
                char* value_without_quotes = (char*)malloc(len - 1);
                if (value_without_quotes) {
                    strncpy(value_without_quotes, lexeme + 1, len - 2);
                    value_without_quotes[len - 2] = '\0';
                    text_values[i] = value_without_quotes;
                } else {
                    // 内存分配失败，使用原始值
                    text_values[i] = strdup(lexeme);
                }
            } else {
                // 没有引号，直接使用原始值
                text_values[i] = strdup(lexeme);
            }
        } else {
            // 对于其他类型（如数字），直接使用lexeme
            text_values[i] = strdup(token.lexeme);
        }
    }
    
    data->values_as_text = text_values;
    plan->params = data;
    return plan;
}

// 生成SELECT执行计划
static PlanNode* generate_select_plan(ASTNode* node, Catalog* catalog) {
    SelectStmt* stmt = (SelectStmt*)node->extra_data;
    
    // 从下往上构建执行计划
    
    // 1. 顺序扫描表
    PlanNode* seq_scan = create_plan_node(PLAN_NODE_SEQSCAN); // 修改枚举值
    SeqScanPlan* seq_scan_data = (SeqScanPlan*)malloc(sizeof(SeqScanPlan));
    seq_scan_data->table_name = strdup(stmt->table_name);
    seq_scan->params = seq_scan_data; // 使用params而不是extra_data
    
    PlanNode* current_plan = seq_scan;
    
    // 2. 如果有WHERE子句，添加过滤节点
    if (stmt->where_clause) {
        PlanNode* filter = create_plan_node(PLAN_NODE_FILTER); // 修改枚举值
        FilterPlan* filter_data = (FilterPlan*)malloc(sizeof(FilterPlan));
        filter_data->condition = deep_copy_ast_node(stmt->where_clause);
        filter->params = filter_data; // 使用params而不是extra_data
        filter->child = current_plan;
        current_plan = filter;
    }
    
    // 3. 添加投影节点（SELECT列表）
    PlanNode* project = create_plan_node(PLAN_NODE_PROJECT); // 修改枚举值
    ProjectPlan* project_data = (ProjectPlan*)malloc(sizeof(ProjectPlan));
    
    // 深拷贝列节点
    project_data->columns = (ASTNode**)malloc(stmt->column_count * sizeof(ASTNode*));
    for (int i = 0; i < stmt->column_count; i++) {
        project_data->columns[i] = deep_copy_ast_node(stmt->columns[i]);
    }
    project_data->column_count = stmt->column_count;
    
    project->params = project_data; // 使用params而不是extra_data
    project->child = current_plan;
    current_plan = project;
    
    return current_plan;
}

// 生成DELETE执行计划
static PlanNode* generate_delete_plan(ASTNode* node, Catalog* catalog) {
    DeleteStmt* stmt = (DeleteStmt*)node->extra_data;
    
    // 1. 顺序扫描表
    PlanNode* seq_scan = create_plan_node(PLAN_NODE_SEQSCAN); // 修改枚举值
    SeqScanPlan* seq_scan_data = (SeqScanPlan*)malloc(sizeof(SeqScanPlan));
    seq_scan_data->table_name = strdup(stmt->table_name);
    seq_scan->params = seq_scan_data; // 使用params而不是extra_data
    
    PlanNode* current_plan = seq_scan;
    
    // 2. 如果有WHERE子句，添加过滤节点
    if (stmt->where_clause) {
        PlanNode* filter = create_plan_node(PLAN_NODE_FILTER); // 修改枚举值
        FilterPlan* filter_data = (FilterPlan*)malloc(sizeof(FilterPlan));
        filter_data->condition = deep_copy_ast_node(stmt->where_clause);
        filter->params = filter_data; // 使用params而不是extra_data
        filter->child = current_plan;
        current_plan = filter;
    }
    
    // 注意：在实际系统中，这里应该添加专门的删除算子
    printf("Warning: DELETE operation is not fully implemented\n");
    
    return current_plan;
}

// 生成DROP TABLE执行计划
static PlanNode* generate_drop_table_plan(ASTNode* node, Catalog* catalog) {
    PlanNode* plan = create_plan_node(PLAN_NODE_DROP);
    DropTableStmt* stmt = (DropTableStmt*)node->extra_data;
    DropParams* data = (DropParams*)malloc(sizeof(DropParams));
    
    data->table_name = strdup(stmt->table_name);
    data->if_exists = stmt->if_exists;
    
    plan->params = data;
    return plan;
}

// 生成ALTER TABLE执行计划
static PlanNode* generate_alter_table_plan(ASTNode* node, Catalog* catalog) {
    PlanNode* plan = create_plan_node(PLAN_NODE_ALTER);
    AlterTableStmt* stmt = (AlterTableStmt*)node->extra_data;
    AlterParams* data = (AlterParams*)malloc(sizeof(AlterParams));
    
    data->table_name = strdup(stmt->table_name);
    
    // 将AlterActionType枚举转换为字符串
    switch (stmt->action) {
        case ALTER_ADD_COLUMN:
            data->action = "ADD";
            break;
        case ALTER_DROP_COLUMN:
            data->action = "DROP";
            break;
        case ALTER_MODIFY_COLUMN:
            data->action = "MODIFY";
            break;
        default:
            data->action = "UNKNOWN";
            break;
    }
    
    data->column_name = stmt->column_name ? strdup(stmt->column_name) : NULL;
    
    // 将ColumnType转换为PlanColType
    switch (stmt->column_type) {
        case TYPE_INT:
            data->column_type = PLAN_COL_INT;
            break;
        case TYPE_VARCHAR:
            data->column_type = PLAN_COL_VARCHAR;
            break;
        default:
            data->column_type = PLAN_COL_INT;
            break;
    }
    
    data->column_length = stmt->column_length;
    
    plan->params = data;
    return plan;
}

// 生成UPDATE执行计划
static PlanNode* generate_update_plan(ASTNode* node, Catalog* catalog) {
    UpdateStmt* stmt = (UpdateStmt*)node->extra_data;
    
    // 1. 顺序扫描表
    PlanNode* seq_scan = create_plan_node(PLAN_NODE_SEQSCAN);
    SeqScanPlan* seq_scan_data = (SeqScanPlan*)malloc(sizeof(SeqScanPlan));
    seq_scan_data->table_name = strdup(stmt->table_name);
    seq_scan->params = seq_scan_data;
    
    PlanNode* current_plan = seq_scan;
    
    // 2. 如果有WHERE子句，添加过滤节点
    if (stmt->where_clause) {
        PlanNode* filter = create_plan_node(PLAN_NODE_FILTER);
        FilterPlan* filter_data = (FilterPlan*)malloc(sizeof(FilterPlan));
        filter_data->condition = deep_copy_ast_node(stmt->where_clause);
        filter->params = filter_data;
        filter->child = current_plan;
        current_plan = filter;
    }
    
    // 3. 添加更新节点
    PlanNode* update = create_plan_node(PLAN_NODE_UPDATE);
    UpdateParams* update_data = (UpdateParams*)malloc(sizeof(UpdateParams));
    
    update_data->table_name = strdup(stmt->table_name);
    update_data->nset = stmt->set_count;
    update_data->col_names = (const char**)malloc(stmt->set_count * sizeof(char*));
    
    const char** values_text = (const char**)malloc(stmt->set_count * sizeof(char*));
    
    for (int i = 0; i < stmt->set_count; i++) {
        update_data->col_names[i] = strdup(stmt->column_names[i]);
        // 简化处理，实际应该根据ASTNode类型提取值
        values_text[i] = strdup("[value]"); // 占位符
    }
    
    update_data->values_as_text = values_text;
    
    if (stmt->where_clause) {
        // 简化处理WHERE条件
        update_data->where_expr = "[where_clause]"; // 占位符
    } else {
        update_data->where_expr = NULL;
    }
    
    update->params = update_data;
    update->child = current_plan;
    current_plan = update;
    
    printf("Warning: UPDATE operation is not fully implemented\n");
    return current_plan;
}

// 生成执行计划的主函数
PlanNode* generate_plan(ASTNode* ast, Catalog* catalog) {
    if (!ast) return NULL;
    
    switch (ast->type) {
        case NODE_CREATE_TABLE:
            return generate_create_table_plan(ast, catalog);
        case NODE_ALTER_TABLE:
            return generate_alter_table_plan(ast, catalog);
        case NODE_UPDATE:
            return generate_update_plan(ast, catalog);
        case NODE_DROP_TABLE:
            return generate_drop_table_plan(ast, catalog);
        case NODE_INSERT:
            return generate_insert_plan(ast, catalog);
        case NODE_SELECT:
            return generate_select_plan(ast, catalog);
        case NODE_DELETE:
            return generate_delete_plan(ast, catalog);
        default:
            printf("Unknown AST node type\n");
            return NULL;
    }
}